package com.scalar.chiptrack.adaptor.sitime.utac;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.AssemblyLot;
import com.scalar.chiptrack.adaptor.utils.ParserResult;
import com.scalar.chiptrack.adaptor.utils.Parser;
import com.scalar.chiptrack.adaptor.utils.ParserFactory;
import com.scalar.chiptrack.adaptor.utils.CSVParserImpl;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.adaptor.dao.NewAdaptorDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.operations.packingslip.forms.PackingSlipForm;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.io.File;

/**
 * Created by IntelliJ IDEA.
 * User: munugoti
 * Date: 16 Apr, 2010
 * Time: 4:53:20 PM
 * To change this template use File | Settings | File Templates.
 */
public class UTACTransactionParser extends JobHandler implements AdaptorConstants
{
    private static Logger m_parserLogger= null;
    private String m_dataOutputDir      = null;

    private HashMap<String, ShippedLot> m_shipDataMap       = new HashMap<String, ShippedLot>();
    private HashMap<String, ShippedLot> m_shipQtyOutDataMap = new HashMap<String, ShippedLot>();
    private HashMap<String, AssemblyLot> m_receiveQtyInMap  = new HashMap<String, AssemblyLot>();
    private HashMap<String, PackingSlipForm> packingSilpMap = new HashMap<String, PackingSlipForm>();

    public UTACTransactionParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_UTAC, LOCATION_TYPE_TEST );
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_UTAC );
            AdaptorDAO.setLogger( m_parserLogger );
            ShippedLotDAO.setLogger( m_parserLogger );
            AdaptorUtils.setLogger( m_parserLogger );
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading/creating UTAC Trnas Parser output directory from database, Exception: " + se);
            throw se;
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main( String args[] ) throws Exception
    {
        try
        {
            new UTACTransactionParser().execute();
        }
        catch (Exception e)
        {
            throw e;
        }
    }
    //Execute Method
   public void execute() throws Exception
   {
       AdaptorUtils.printHeader(VENDOR_NAME_UTAC + " FTP", CONSTANT_PARSER );

       File doneDestDir = new File( m_dataOutputDir + "/done" );

       File wipDataoutDir = new File( m_dataOutputDir );

       File[] fileList = wipDataoutDir.listFiles();

       if ( ( fileList == null ) || ( fileList.length <= 3 ) )
       {
           log( "No file found in directory: " + wipDataoutDir );
           throw new ScalarException( "No file found in directory: " + wipDataoutDir + "----\n\n" );
       }

       ArrayList<File> successFileList   = new ArrayList<File>();
       boolean success             = false;

       try
       {
           for ( int i = 0; i < fileList.length; i++ )
           {
               if ( fileList[i].isDirectory())
               {
                   continue;
               }

               /*if ( ( fileList[i].getName() != null ) && fileList[i].getName().trim().startsWith( UTACFTPAdaptor.FILE_NAME_TRANSACTION ) )
               {
                   parseDailyTransactionReport ( fileList[i].getAbsolutePath() );

                   successFileList.add( fileList[i] );
               }*/
               if ( ( fileList[i].getName() != null ) && fileList[i].getName().trim().startsWith( UTACFTPAdaptor.FILE_NAME_SHIP ) )
               {
                   parseShipReport ( fileList[i].getAbsolutePath() );

                   successFileList.add( fileList[i] );
               }
           }
           success = true;
       }
       catch ( Exception e )
       {
           success = false;
           log( "ERROR!! ERROR!! ERROR!! While parsing UTAC Trans Yield Report and storing File " + e );
           e.printStackTrace();
           throw e;
       }

       try
       {
           if ( !m_receiveQtyInMap.isEmpty() )
           {
               log(" Saving the In Transaction report information");

               AdaptorDAO.saveInTransactionData( null, m_receiveQtyInMap.values().iterator() );
           }
           success = true;
       }
       catch (Exception e)
       {
           success = false;
            e.printStackTrace();
            log( "ERROR!! ERROR!! ERROR!! Could not update Assembly Yield Lot information into database: " + e );
            throw e;
       }
       try
        {
            // Save Out Transactions
            if ( m_shipQtyOutDataMap.isEmpty() == false )
            {
                log( " Updating Out Transaction Lot Information" );
                AdaptorDAO.saveOutTransactionData( null, m_shipQtyOutDataMap.values().iterator() );
            }
            success = true;
            m_shipQtyOutDataMap.clear();
            m_shipQtyOutDataMap = null;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log( "ERROR!! ERROR!! ERROR!! Could not update Out Transaction Lot information into database: " + se );
            throw se;
        }
        if ( !packingSilpMap.isEmpty() )
        {
            AdaptorDAO.updatePackingSlipData( null, packingSilpMap.values().iterator() );
        }

        try
        {
            // Save FG Ship Information
            if ( m_shipDataMap.isEmpty() == false )
            {
                log( " Updating Shiping Lot Information" );
                ShippedLotDAO.saveShippedLot( null, m_shipDataMap.values().iterator() );
            }
            success = true;
            m_shipDataMap.clear();
            m_shipDataMap = null;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log( "ERROR!! ERROR!! ERROR!! Could not update Shipping Lot information into database: " + se );
            throw se;
        }
	    int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( UTACFTPAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, UTACFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, UTACFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }
        // Move the successful files to 'done' directory
        if ( success )
        {
            AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
        }
   }//end of execute method

    private void parseDailyTransactionReport( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result     = null;
        ShippedLot shippedLot   = null;
        AssemblyLot assemblyLot = null;
        String lotNumber        = null;
        String partNumber       = null;

        try
        {
            File detailWipFile = new File( fileName );
            if ( detailWipFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "\nParsing the file for Transaction Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Transaction Report..." );

            Parser parser = ParserFactory.getCSVParser( detailWipFile, ',' );

            ((CSVParserImpl)parser).setHeaderRowIdx(2);
            ((CSVParserImpl)parser).setDataStartRowIdx(3);

            result = parser.parse();
            if ( result == null || result.getHeadings() == null)
            {
                System.out.println(" ******************** Header Row not Found ********************** ");
                return;
            }
            //System.out.println("result.getHeadings() = " + result.getHeadings());
            if ( result != null )
            {
                while ( result.next() )
                {
                    partNumber = result.getString("Custdevice");
                    lotNumber   =  result.getString("Custlotnum");

                    String transactionDate         = null;
                    transactionDate  = result.getString("Transaction Time");

                    if ( partNumber != null && partNumber.trim().length() >0 && lotNumber != null && lotNumber.trim().length() > 0 )
                    {
                        if ( result.getString("Process Stage") != null &&
                         ( "POST_TEST_OUT".equalsIgnoreCase( result.getString("Process Stage") ) || "TEST_OUT".equalsIgnoreCase( result.getString("Process Stage") )
                            || "ASSEMBLY_OUT".equalsIgnoreCase( result.getString("Process Stage") ) || "TNR_OUT".equalsIgnoreCase( result.getString("Process Stage") ) ) )
                        {

                           shippedLot = ( ShippedLot ) m_shipQtyOutDataMap.get ( partNumber + lotNumber + transactionDate );

                           if ( shippedLot == null )
                           {
                                shippedLot = new ShippedLot();
                                m_shipQtyOutDataMap.put( partNumber + lotNumber + transactionDate, shippedLot );
                           }

                           int quantity = 0;
                           if ( shippedLot.getShipQty() != null )
                           {
                               try
                               {
                                   quantity = Integer.parseInt( shippedLot.getShipQty() );
                               }
                               catch ( NumberFormatException ignore )
                               {
                                   quantity = 0;
                               }
                               quantity += result.getInt("Dieqty");

                           }
                           else
                           {
                             quantity = result.getInt("Dieqty");
                           }

                           if ( quantity > 0 )
                           {
                               if ("POST_TEST_OUT".equalsIgnoreCase( result.getString("Process Stage") ) )
                               {
                                   shippedLot.setProcessType(LOCATION_TYPE_PRE_TEST);
                                   shippedLot.setCurrentLocation(LOCATION_TYPE_CLASS_STORE);
                               }
                               else if ( "TEST_OUT".equalsIgnoreCase( result.getString("Process Stage") ) )
                               {
                                   shippedLot.setProcessType(WIP_TEST_TYPE_FT);
                                   shippedLot.setCurrentLocation(WIP_TYPE_TEST);
                               }
                               else if ("ASSEMBLY_OUT".equalsIgnoreCase( result.getString("Process Stage") ) )
                               {
                                   shippedLot.setProcessType(WIP_TYPE_ASSEMBLY);
                                   shippedLot.setCurrentLocation(WIP_TYPE_ASSEMBLY);
                               }
                               else if ("TNR_OUT".equalsIgnoreCase( result.getString("Process Stage") ) )
                               {
                                   shippedLot.setProcessType(LOCATION_TYPE_TAPE_REEL);
                                   shippedLot.setCurrentLocation(LOCATION_TYPE_CLASS_STORE);
                               }
                               shippedLot.setVendorName(VENDOR_NAME_UTAC);
                               shippedLot.setLotNumber( lotNumber );
                               shippedLot.setPartNumber( partNumber );
                               shippedLot.setShipDate( transactionDate );
                               shippedLot.setShipQty( quantity + "" );
                               shippedLot.setFabLotNumber( lotNumber );
                           }
                       }

                       //Received QTY
                       if ( result.getString("Process Stage") != null &&
                         ( "POST_TEST_IN".equalsIgnoreCase( result.getString("Process Stage") ) || "FG_IN".equalsIgnoreCase( result.getString("Process Stage") )
                            || "TEST_IN".equalsIgnoreCase( result.getString("Process Stage") ) || "ASSEMBLY_IN".equalsIgnoreCase( result.getString("Process Stage") )
                            || "TNR_IN".equalsIgnoreCase( result.getString("Process Stage") ) ) )
                       {
                           String psType = null;
                           if ("POST_TEST_IN".equalsIgnoreCase( result.getString("Process Stage") ) )
                           {
                                psType = LOCATION_TYPE_PRE_TEST;
                           }
                           else if ("FG_IN".equalsIgnoreCase( result.getString("Process Stage") ) )
                           {
                                int pretestProcessSepId = NewAdaptorDAO.getProcessStepId( partNumber, LOCATION_TYPE_CLASS_STORE, LOCATION_TYPE_PRE_TEST );
                                if ( pretestProcessSepId > 0 )
                                {
                                   psType =LOCATION_TYPE_PRE_TEST;
                                }
                                else
                                {
                                    psType =LOCATION_TYPE_FG;
                                }

                           }
                           else if ( "TEST_IN".equalsIgnoreCase( result.getString("Process Stage") ) )
                           {
                                psType= WIP_TEST_TYPE_FT;
                           }
                           else if ("ASSEMBLY_IN".equalsIgnoreCase( result.getString("Process Stage") ) )
                           {
                               psType = WIP_TYPE_ASSEMBLY;
                           }
                           else if ("TNR_IN".equalsIgnoreCase( result.getString("Process Stage") ) )
                           {
                               psType = LOCATION_TYPE_TAPE_REEL;
                           }
                           assemblyLot = (AssemblyLot) m_receiveQtyInMap.get( partNumber + lotNumber + psType + transactionDate );

                           if (assemblyLot == null)
                           {
                               assemblyLot = new AssemblyLot( VENDOR_NAME_UTAC);
                               m_receiveQtyInMap.put( partNumber + lotNumber+ psType+ transactionDate , assemblyLot );
                           }

                           int assyQtyIn = 0;
                           if ( assemblyLot.getQtyIn() != null)
                           {
                               try
                               {
                                   assyQtyIn = Integer.parseInt( assemblyLot.getQtyIn() );
                               }
                               catch ( NumberFormatException ignore )
                               {
                                   assyQtyIn = 0;
                               }

                               assyQtyIn += result.getInt("Dieqty");

                           }
                           else
                           {
                               assyQtyIn = result.getInt("Dieqty");
                           }

                           if ( assyQtyIn > 0 )
                           {
                               assemblyLot.setProcessType( psType );
                               assemblyLot.setQtyIn( assyQtyIn +"");
                               assemblyLot.setDateIn( transactionDate );
                               assemblyLot.setLotNumber( lotNumber );
                               assemblyLot.setDeviceName( partNumber );
                               assemblyLot.setFabLotNumber( lotNumber );
                           }
                       }

                    }
                }
            }    
        }
        catch(Exception ex)
        {
            System.out.println("ERROR!!!ERROR!!! While Parsing the UTAC Transaction Report");
            ex.printStackTrace();
            throw ex;

        }
    }

    private void parseShipReport( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result     = null;
        PackingSlipForm packingSlipForm = null;
        String partNumber = null;
        String lotNumber  = null;
        String shipDate   = null;
        String shipTo     = null;
        ShippedLot shippedLot = null;
        try
        {
            File detailWipFile = new File( fileName );
            if ( detailWipFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "\nParsing the file for Ship Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Ship Report..." );

            Parser parser = ParserFactory.getCSVParser( detailWipFile, ',' );

            ((CSVParserImpl)parser).setHeaderRowIdx(2);
            ((CSVParserImpl)parser).setDataStartRowIdx(3);

            result = parser.parse();
            if ( result == null || result.getHeadings() == null)
            {
                System.out.println(" ******************** Header Row not Found ********************** ");
                return;
            }
            while ( result.next() )
            {
                partNumber = result.getString("Target Device");
                lotNumber  = result.getString("Lotno");
                shipDate   = result.getString("Shipdate");
                shipTo     = result.getString("Ship To");
                if ("SITIME RESIDENT".equalsIgnoreCase( shipTo ) )
                {
                    shipTo     = result.getString("Ship to Address").split(" ")[0];    
                }
                if ( result.getString("Drop Flag") != null && result.getString("Drop Flag").trim().length() >0
                        && "Y".equalsIgnoreCase( result.getString("Drop Flag") ) && result.getString("Packing Slip No") != null && result.getString("Packing Slip No").trim().length() > 0 )
                {
                    packingSlipForm = new PackingSlipForm();
                    packingSlipForm.setNoOfBoxes( result.getString("No Of Boxes"));
                    packingSlipForm.setWeight( result.getString("Gross Weight"));
                    packingSlipForm.setLabel(result.getString("Packing Slip No") );
                    packingSlipForm.setHawb(result.getString("Hawb") );
                    packingSlipForm.setAirWayBillNo( result.getString("Hawb") );
                    packingSlipForm.setEtd(result.getString("Etd") );
                    packingSlipForm.setEta(result.getString("Eta") );
                    if ( !packingSilpMap.containsKey( result.getString("Packing Slip No") ) )
                    {
                        packingSilpMap.put( result.getString("Packing Slip No"), packingSlipForm);
                    }
                }
                //SHIPMENT DATA
                if ( partNumber != null && partNumber.trim().length() > 0 && lotNumber != null && lotNumber.trim().length() > 0 )
                {
                    if ( result.getString("Drop Flag") != null && result.getString("Drop Flag").trim().length() >0
                            && ( "N".equalsIgnoreCase( result.getString("Drop Flag") ) || ( "Y".equalsIgnoreCase( result.getString("Drop Flag") ) && result.getString("Packing Slip No") == null ) ) )
                    {
                        int pretestProcessSepId = NewAdaptorDAO.getProcessStepId( partNumber, LOCATION_TYPE_CLASS_STORE, LOCATION_TYPE_PRE_TEST );
                        if ( pretestProcessSepId <= 0 )
                        {
                            /*shippedLot = (ShippedLot) m_shipDataMap.get(partNumber + lotNumber + shipDate + shipTo);
                            if (shippedLot == null)
                            {
                                shippedLot = new ShippedLot(VENDOR_NAME_UTAC, LOCATION_TYPE_CLASS_STORE );
                                m_shipDataMap.put(partNumber + lotNumber + shipDate + shipTo, shippedLot);
                            }
                            shippedLot.setProcessType( LOCATION_TYPE_PRE_TEST );
                        }
                        else
                        {  */
                            shippedLot = (ShippedLot) m_shipDataMap.get(partNumber + lotNumber + shipDate + shipTo);
                            if (shippedLot == null)
                            {
                                shippedLot = new ShippedLot(VENDOR_NAME_UTAC, LOCATION_TYPE_FG );
                                m_shipDataMap.put(partNumber + lotNumber + shipDate + shipTo, shippedLot);
                            }
                            shippedLot.setProcessType( LOCATION_TYPE_FG );
                            shippedLot.setDorpShipment( false );
                        }

                        int quantity = 0;
                        if ( shippedLot.getShipQty() != null )
                        {
                           try
                           {
                               quantity = Integer.parseInt( shippedLot.getShipQty() );
                           }
                           catch ( NumberFormatException ignore )
                           {
                               quantity = 0;
                           }
                           try
                           {
                               quantity += result.getInt("Ship Die Qty");
                           }
                           catch ( NumberFormatException ignore )
                           {
                               quantity = 0;
                           }
                        }
                        else
                        {
                           try
                           {
                               quantity = result.getInt("Ship Die Qty");
                           }
                           catch ( NumberFormatException ignore )
                           {
                               quantity = 0;
                           }
                        }
                        if ( quantity > 0 )
                        {
                            shippedLot.setLotNumber( lotNumber );
                            shippedLot.setPartNumber( partNumber.trim() );
                            shippedLot.setShipDate( shipDate );
                            shippedLot.setShipQty( quantity + "");
                            shippedLot.setMawb( "N/A".equalsIgnoreCase(result.getString("Mawb")) ? null : result.getString("Mawb"));
                            shippedLot.setHawb(  "N/A".equalsIgnoreCase(result.getString("Hawb")) ? null : result.getString("Hawb") );
                            shippedLot.setFlightNumber( "N/A".equalsIgnoreCase(result.getString("Fltno")) ? null : result.getString("Fltno") );
                            shippedLot.setEtd( result.getString("Etd"));
                            shippedLot.setEta( result.getString("Eta"));
                            shippedLot.setInvoiceNumber( result.getString("Invoice No") );
                            shippedLot.setCustomerPO(result.getString("Cust Po"));
                            shippedLot.setNextLocation( shipTo );
                            shippedLot.setFabLotNumber( lotNumber );

                        }
                    }
                }
            }
        }
        catch(Exception ex)
        {
            System.out.println("ERROR!!!ERROR!!! While Parsing the UTAC Ship Report");
            ex.printStackTrace();
            throw ex;

        }
    }

    private static void log( String message )
    {

        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }
}

